//
//  RegBarsAppDelegate.m
//  RegBars
//
//  Created by Huu Nhat on 7/25/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "RegBarsAppDelegate.h"
#import "DateTimeHelper.h"
#import "RestaurantDetailParser.h"
#import "WeekCSVParser.h"
#import "GANTracker.h"

// Dispatch period in seconds
static const NSInteger kGANDispatchPeriodSec = 20;


@implementation RegBarsAppDelegate

@synthesize window = _window;
@synthesize date;
@synthesize restaurantDict;
@synthesize currentWeek;
@synthesize nextWeek;
@synthesize mondayPlans;
@synthesize tuesdayPlans;
@synthesize wednesdayPlans;
@synthesize thursdayPlans;
@synthesize fridayPlans;

@synthesize nextmondayPlans;
@synthesize nexttuesdayPlans;
@synthesize nextwednesdayPlans;
@synthesize nextthursdayPlans;
@synthesize nextfridayPlans;
@synthesize currentDayValue;
@synthesize currentCityId;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    planParseCount = 0;
	currentWeek = [[NSMutableArray alloc] init];
	nextWeek = [[NSMutableArray alloc] init];
	
	WeekCSVParser *currentWeekParser = [[[WeekCSVParser alloc] init] autorelease];
	[currentWeekParser getWeekFromUrl:WeeklyCSVUrl withDelegate:self storeInArray:currentWeek];
	
	WeekCSVParser *nextWeekParser = [[[WeekCSVParser alloc] init] autorelease];
	[nextWeekParser getWeekFromUrl:NextWeekCSVUrl withDelegate:self storeInArray:nextWeek];
	
	[self calculateDate];
	
	RestaurantDetailParser *parser = [[RestaurantDetailParser alloc] init];
	[parser loadRestaurantList:RestaurantListURL withDelegate:self];
	[parser release];
    
    //Google Analytics Tracking
    [[GANTracker sharedTracker] startTrackerWithAccountID:kGAUserId
                                           dispatchPeriod:kGANDispatchPeriodSec
                                                 delegate:nil];
    
    NSError *error;
    if (![[GANTracker sharedTracker] setCustomVariableAtIndex:1
                                                         name:@"iPhone1"
                                                        value:@"iv1"
                                                    withError:&error]) {
        // Handle error here
    }
    
    if (![[GANTracker sharedTracker] trackEvent:@"my_category"
                                         action:@"my_action"
                                          label:@"my_label"
                                          value:-1
                                      withError:&error]) {
        // Handle error here
    }
    
    if (![[GANTracker sharedTracker] trackPageview:@"/app_entry_point"
                                         withError:&error]) {
        // Handle error here
    }

    
	[self.window makeKeyAndVisible];
    
    return YES;
}

#pragma mark -
#pragma mark Check Network

- (BOOL) connectedToNetwork {
    // Create zero addy
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;
    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
    if (!didRetrieveFlags){
        NSLog(@"Error. Could not recover network reachability flags\n");
        return 0;
    }
    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    return (isReachable && !needsConnection) ? YES : NO;
}

- (void)didEndParseCSVFile:(NSMutableArray*) weekArray withUrl:(NSString *)urlString{
	//NSLog(@"CSV content = %@", weekArray);
	planParseCount ++;
	if ([urlString isEqualToString:WeeklyCSVUrl]) {
		[self initCurrentWeekPlans];
	} else {
		[self initNextWeekPlans];
	}
}

- (void) initCurrentWeekPlans{
	mondayPlans = [[NSMutableArray alloc] init];
	tuesdayPlans = [[NSMutableArray alloc] init];
	wednesdayPlans = [[NSMutableArray alloc] init];
	thursdayPlans = [[NSMutableArray alloc] init];
	fridayPlans = [[NSMutableArray alloc] init];
    BOOL mutiMonth = NO;
    int numOfMonth = 0, virtualMonth = 0;
    for (Week *week in currentWeek){
        int monthOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:1] intValue];
        if (monthOfWeek > virtualMonth) {
            numOfMonth++;
        }
    }
    if (numOfMonth > 1) {
        mutiMonth = YES;
    }
    if (mutiMonth) {
        Week *randomWeek = [currentWeek objectAtIndex:0];
        int lastDayFirstMonth = 0;
        int startDayNextMonth = 32;
        int monday = [[[randomWeek.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
        int month = [[[randomWeek.date componentsSeparatedByString:@"."] objectAtIndex:1] intValue];
        for (Week *week in currentWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            int monthOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:1] intValue]; 
            if ((dayOfWeek < monday) && (monthOfWeek <= month)) {
                monday = dayOfWeek;
            }
            if (dayOfWeek > lastDayFirstMonth) {
                lastDayFirstMonth = dayOfWeek;
            }
            if (startDayNextMonth > dayOfWeek) {
                startDayNextMonth = dayOfWeek;
            }
        }
        int dateBreak = lastDayFirstMonth - monday;
        for (Week *week in currentWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            if (dayOfWeek == monday) {
                [mondayPlans addObject:week];
            }
            if (dayOfWeek == (monday+1)) {
                [tuesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+2)) {
                [wednesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+3)) {
                [thursdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+4)) {
                [fridayPlans addObject:week];
            }
            if (dayOfWeek == startDayNextMonth) {
                switch (dateBreak) {
                    case 0:
                        [tuesdayPlans addObject:week];
                        break;
                    case 1:
                        [wednesdayPlans addObject:week];
                        break;
                    case 2:
                        [thursdayPlans addObject:week];
                        break;
                    case 3:
                        [fridayPlans addObject:week];
                        break;
                }
            }
            if (dayOfWeek == (startDayNextMonth +1)) {
                switch (dateBreak) {
                    case 0:
                        [wednesdayPlans addObject:week];
                        break;
                    case 1:
                        [thursdayPlans addObject:week];
                        break;
                    case 2:
                        [fridayPlans addObject:week];
                        break;
                }
            }
            if (dayOfWeek == (startDayNextMonth+2)) {
                switch (dateBreak) {
                    case 0:
                        [thursdayPlans addObject:week];
                        break;
                    case 1:
                        [fridayPlans addObject:week];
                        break;
                }
            }
            if (dayOfWeek == (startDayNextMonth+3)) {
                switch (dateBreak) {
                    case 0:
                        [fridayPlans addObject:week];
                        break;
                }
            }
        }
    } else {
        //find monday
        int monday = 32;
        for (Week *week in currentWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            if (dayOfWeek < monday) {
                monday = dayOfWeek;
            }
        }
        NSLog(@"Monday = %d", monday);
        //init
        for (Week *week in currentWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            if (dayOfWeek == monday) {
                [mondayPlans addObject:week];
            }
            if (dayOfWeek == (monday+1)) {
                [tuesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+2)) {
                [wednesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+3)) {
                [thursdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+4)) {
                [fridayPlans addObject:week];
            }
        }
    }
}

- (void) initNextWeekPlans{
	nextmondayPlans = [[NSMutableArray alloc] init];
	nexttuesdayPlans = [[NSMutableArray alloc] init];
	nextwednesdayPlans = [[NSMutableArray alloc] init];
	nextthursdayPlans = [[NSMutableArray alloc] init];
	nextfridayPlans = [[NSMutableArray alloc] init];
	BOOL mutiMonth = NO;
    int numOfMonth = 0, virtualMonth = 0;
    for (Week *week in nextWeek){
        int monthOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:1] intValue];
        if (monthOfWeek > virtualMonth) {
            numOfMonth++;
        }
    }
    if (numOfMonth > 1) {
        mutiMonth = YES;
    }
    if (mutiMonth) {
        Week *randomWeek = [nextWeek objectAtIndex:0];
        int lastDayFirstMonth = 0;
        int startDayNextMonth = 32;
        int monday = [[[randomWeek.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
        int month = [[[randomWeek.date componentsSeparatedByString:@"."] objectAtIndex:1] intValue];
        for (Week *week in nextWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            int monthOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:1] intValue]; 
            if ((dayOfWeek < monday) && (monthOfWeek <= month)) {
                monday = dayOfWeek;
            }
            if (dayOfWeek > lastDayFirstMonth) {
                lastDayFirstMonth = dayOfWeek;
            }
            if (startDayNextMonth > dayOfWeek) {
                startDayNextMonth = dayOfWeek;
            }
        }
        int dateBreak = lastDayFirstMonth - monday;
        for (Week *week in nextWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            if (dayOfWeek == monday) {
                [nextmondayPlans addObject:week];
            }
            if (dayOfWeek == (monday+1)) {
                [nexttuesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+2)) {
                [nextwednesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+3)) {
                [nextthursdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+4)) {
                [nextfridayPlans addObject:week];
            }
            if (dayOfWeek == startDayNextMonth) {
                switch (dateBreak) {
                    case 0:
                        [nexttuesdayPlans addObject:week];
                        break;
                    case 1:
                        [nextwednesdayPlans addObject:week];
                        break;
                    case 2:
                        [nextthursdayPlans addObject:week];
                        break;
                    case 3:
                        [nextfridayPlans addObject:week];
                        break;
                }
            }
            if (dayOfWeek == (startDayNextMonth +1)) {
                switch (dateBreak) {
                    case 0:
                        [nextwednesdayPlans addObject:week];
                        break;
                    case 1:
                        [nextthursdayPlans addObject:week];
                        break;
                    case 2:
                        [nextfridayPlans addObject:week];
                        break;
                }
            }
            if (dayOfWeek == (startDayNextMonth+2)) {
                switch (dateBreak) {
                    case 0:
                        [nextthursdayPlans addObject:week];
                        break;
                    case 1:
                        [nextfridayPlans addObject:week];
                        break;
                }
            }
            if (dayOfWeek == (startDayNextMonth+3)) {
                switch (dateBreak) {
                    case 0:
                        [nextfridayPlans addObject:week];
                        break;
                }
            }
        }
    } else {
        //find monday
        int monday = 32;
        for (Week *week in nextWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            if (dayOfWeek < monday) {
                monday = dayOfWeek;
            }
        }
        NSLog(@"Monday = %d", monday);
        //init
        for (Week *week in nextWeek) {
            int dayOfWeek = [[[week.date componentsSeparatedByString:@"."] objectAtIndex:0] intValue];
            if (dayOfWeek == monday) {
                [nextmondayPlans addObject:week];
            }
            if (dayOfWeek == (monday+1)) {
                [nexttuesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+2)) {
                [nextwednesdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+3)) {
                [nextthursdayPlans addObject:week];
            }
            if (dayOfWeek == (monday+4)) {
                [nextfridayPlans addObject:week];
            }
        }
    }
}

- (void)didEndGetRestaurantsDetail:(NSMutableDictionary *)Dict{
    NSLog(@"didEndGetRestaurantsDetail : %@",Dict);
	restaurantDict = [[NSMutableDictionary alloc] initWithDictionary:Dict];
	[Dict release];
}

- (void) calculateDate{
    DateTimeHelper *dateHelper = [[[DateTimeHelper alloc] init] autorelease];
	NSString *dateString = [[dateHelper calculateDate:[NSDate date]] copy];
    NSLog(@"[NSDate date] %@",[NSDate date]);
	if ([dateString isEqualToString:Monday]) {
		date = 2;
	}else if ([dateString isEqualToString:Tuesday]) {
		date = 3;
	}else if ([dateString isEqualToString:Wednesday]) {
		date = 4;
	}else if ([dateString isEqualToString:Thursday]) {
		date = 5;
	}else if ([dateString isEqualToString:Friday]) {
		date = 6;
	}else if ([dateString isEqualToString:Saturday]) {
		date = 7;
	}else if ([dateString isEqualToString:Sunday]) {
		date = 8;
	}
    currentDayValue = date;
    NSLog(@" Date %d",date);
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

- (void)dealloc
{
	[mondayPlans release];
	[tuesdayPlans release];
	[wednesdayPlans release];
	[thursdayPlans release];
	[fridayPlans release];
	
	[nextmondayPlans release];
	[nexttuesdayPlans release];
	[nextwednesdayPlans release];
	[nextthursdayPlans release];
	[nextfridayPlans release];
	[currentWeek release];
	[nextWeek release];
    [_window release];
    [currentCityId release];
    [super dealloc];
}

@end
